/**
 * 
 */
package com.music.twitter.controllers;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.http.AccessToken;
import twitter4j.http.RequestToken;
import static com.music.twitter.constants.TwitterConstants.*;
import com.music.service.members.beans.Member;
import com.music.twitter.beans.TwitterClientBean;
import com.music.twitter.beans.TwitterConfig;
import com.music.twitter.client.TwitterClient;
import com.music.twitter.constants.TwitterConstants;
import com.music.twitter.logging.TwitterLogger;

/**
 * @author asanthan
 * 
 */
public class TwitterHomeController implements Controller {

	private String mViewName;

	private String mExceptionView;

	private TwitterClient mTwitterClient;

	private TwitterConfig mTwitterConfig;

	private static final Logger log = TwitterLogger.getLogger();

	public ModelAndView handleRequest(HttpServletRequest pRequest,
			HttpServletResponse pResponse) throws ServletException, IOException {
		log.debug("Entering TwitterHomeController...");
		System.out.println("Entering TwitterHomeController...");
		ModelAndView modelAndView = new ModelAndView();
		Long memberId = null;

		memberId = getMemberId(pRequest);
		log.debug("memberId=" + memberId);
		if (memberId == null) {
			return new ModelAndView(getExceptionView(),
					TwitterConstants.EXCEPTION_MESSAGE, "Invalid MemberId ");
		}

		Twitter twitter = new Twitter();
		twitter.setOAuthConsumer(getConsumerKey(), getConsumerSecret());

		TwitterClientBean twitterClientBean = getTwitterClient().getTwitter(
				memberId);

		// Member is not yet registered to twitter from our site.
		if (twitterClientBean == null) {

			String pOAuthToken = pRequest.getParameter("oauth_token");
			Map parameterMap = pRequest.getParameterMap();
			for(Object key:parameterMap.keySet()){
				System.out.println("Key="+key+":Value="+parameterMap.get(key));
			}

			System.out.println("oauth_token=" + pOAuthToken);
			RequestToken authRequestToken = null;
			try {
				// Visiting first time. Redirect to twitterAuthUrl.
				if (pOAuthToken == null) {
					// Get request token from callback url.
					authRequestToken = twitter.getOAuthRequestToken();
					
					System.out.println("RequentToken=" + authRequestToken);
			
					String authorizeUrl = authRequestToken.getAuthorizationURL();
					modelAndView.setViewName("login");
					modelAndView.addObject("authUrl", authorizeUrl);
					System.out.println("Authurl=" + authorizeUrl);
					pResponse.addCookie(new Cookie("oauth_token",authRequestToken.getToken()));
					pResponse.addCookie(new Cookie("oauth_token_secret",authRequestToken.getTokenSecret()));
					System.out.println("Cookies created");
					return modelAndView;
				} else {
					// Get access token .
					String oauthToken = null,oauthTokenSecret = null;
					Cookie[] cookies = pRequest.getCookies();
					for(Cookie cookie:cookies){
						if(cookie.getName().equals("oauth_token")){
							oauthToken = cookie.getValue();
						}else if(cookie.getName().equals("oauth_token_secret")){
							oauthTokenSecret = cookie.getValue();
						}
					}
					System.out.println("oauth_verifier="+pRequest.getParameter("oauth_verifier"));
					System.out.println("oauth_token="+oauthToken+"\toauth_secret="+oauthTokenSecret);
					AccessToken accessToken = twitter.getOAuthAccessToken( oauthToken,oauthTokenSecret);

					twitter.setOAuthAccessToken(accessToken);
					System.out.println("AccessToken=" + accessToken);
					twitterClientBean = new TwitterClientBean();
					twitterClientBean.setAccessToken(accessToken);
					twitterClientBean.setMemberId(memberId);
					twitterClientBean.setTwitterId(twitter.getUserId());
					twitterClientBean = getTwitterClient().insertTwitter(twitterClientBean);
				}
			} catch (TwitterException e) {
				System.out.println("Exception while getting access token");
				e.printStackTrace();
			}

		} else {
			// get acess token from db and set it to twitter.
			System.out.println("Got access token from db");
			twitter.setOAuthAccessToken(twitterClientBean.getAccessToken());
		}

		List<Status> userTimeline = null;
		try {
			userTimeline = twitter.getUserTimeline();
		} catch (TwitterException e) {
			System.out.println("Exceptin while getting timeline");
			e.printStackTrace();
		}
		System.out.println("userid=" + twitterClientBean.getTwitterId());
		System.out.println("userAgent=" + twitter.getUserAgent());
		modelAndView.addObject(TWITTER_USER_ID, twitterClientBean.getTwitterId());
		modelAndView.addObject(TWITTER_USER_TIMELINE, userTimeline);
		modelAndView.setViewName(getViewName());

		return modelAndView;
	}

	private String getConsumerSecret() {
		return getTwitterConfig().getConsumerSecret();
	}

	private String getConsumerKey() {
		return getTwitterConfig().getConsumerKey();
	}

	/**
	 * 
	 * @param pRequest
	 * @return
	 */
	private Long getMemberId(HttpServletRequest pRequest) {
		Member member = (Member) pRequest.getAttribute("member");
		return member.getMemberId();
	}

	/**
	 * @return the viewName
	 */
	public String getViewName() {
		return mViewName;
	}

	/**
	 * @param pViewName
	 *            the viewName to set
	 */
	@Required
	public void setViewName(String pViewName) {
		mViewName = pViewName;
	}

	/**
	 * @return the exceptionView
	 */
	public String getExceptionView() {
		return mExceptionView;
	}

	/**
	 * @param pExceptionView
	 *            the exceptionView to set
	 */
	@Required
	public void setExceptionView(String pExceptionView) {
		mExceptionView = pExceptionView;
	}

	/**
	 * @return the twitterClient
	 */
	public TwitterClient getTwitterClient() {
		return mTwitterClient;
	}

	/**
	 * @param pTwitterClient
	 *            the twitterClient to set
	 */
	@Required
	public void setTwitterClient(TwitterClient pTwitterClient) {
		mTwitterClient = pTwitterClient;
	}

	/**
	 * @return the twitterConfig
	 */
	public TwitterConfig getTwitterConfig() {
		return mTwitterConfig;
	}

	/**
	 * @param pTwitterConfig
	 *            the twitterConfig to set
	 */
	@Required
	public void setTwitterConfig(TwitterConfig pTwitterConfig) {
		mTwitterConfig = pTwitterConfig;
	}

}